﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Xunit;

using Windy.Transformations;

namespace Windy.Transformations.Test
{
    public class TransformRuleTests
    {
        [Fact()]
        public void BlockTransformRuleTest()
        {
            TransformRuleTypes ruleType = TransformRuleTypes.VoidTransformRule;

            var equalRule = new BlockTransformRule<int>(1);
            var predictRule = new BlockTransformRule<int>((i) => i % 2 == 0);

            Assert.Equal(ruleType, equalRule.RuleType);
            Assert.Equal(ruleType, equalRule.RuleType);

            Assert.True(equalRule.CheckCondition(1));
            Assert.False(equalRule.CheckCondition(2));

            Assert.False(predictRule.CheckCondition(1));
            Assert.True(predictRule.CheckCondition(2));
        }

        [Fact]
        public void TransferTransformRuleTest()
        {
            TransformRuleTypes ruleType = TransformRuleTypes.MonoTransformRule;

            var equalRule = new TransferTransformRule<int, int>(1);
            var predictRule = new TransferTransformRule<int, int>((i) => i % 2 == 0);

            Assert.Equal(ruleType, equalRule.RuleType);
            Assert.Equal(ruleType, equalRule.RuleType);

            Assert.True(equalRule.CheckCondition(1));
            Assert.False(equalRule.CheckCondition(2));

            Assert.False(predictRule.CheckCondition(1));
            Assert.True(predictRule.CheckCondition(2));

            Assert.Equal(1, equalRule.GenerateOutput(1, 1));
            Assert.Equal(2, predictRule.GenerateOutput(2, 2));
        }

        [Fact]
        public void ReplaceTransformRuleTest()
        {
            TransformRuleTypes ruleType = TransformRuleTypes.MonoTransformRule;

            var equalRule = new ReplaceTransformRule<int, int, int>(1, (i) => i + 1);
            var predictRule = new ReplaceTransformRule<int, int, int>((i) => i % 2 == 0, (i) => i + 1);

            Assert.Equal(ruleType, equalRule.RuleType);
            Assert.Equal(ruleType, equalRule.RuleType);

            Assert.True(equalRule.CheckCondition(1));
            Assert.False(equalRule.CheckCondition(2));

            Assert.False(predictRule.CheckCondition(1));
            Assert.True(predictRule.CheckCondition(2));

            Assert.Equal(2, equalRule.GenerateOutput(1, 1));
            Assert.Equal(3, predictRule.GenerateOutput(2, 2));
        }


        [Fact()]
        public void ExpandTransformRuleTest()
        {
            TransformRuleTypes ruleType = TransformRuleTypes.VaryTransformRule;

            var equalRule = new ExpandTransformRule<int, int, int>(1, TestOutputGenerators.Repeat);
            var predictRule = new ExpandTransformRule<int, int, int>((i) => i % 2 == 0, TestOutputGenerators.Repeat);

            Assert.Equal(ruleType, equalRule.RuleType);
            Assert.Equal(ruleType, equalRule.RuleType);

            Assert.True(equalRule.CheckCondition(1));
            Assert.False(equalRule.CheckCondition(2));

            Assert.False(predictRule.CheckCondition(1));
            Assert.True(predictRule.CheckCondition(2));

            Assert.Equal(new int[] { 2, 2 }, equalRule.GenerateOutput(2, 2).ToArray());
            Assert.Equal(new int[] { 4, 4, 4, 4 }, predictRule.GenerateOutput(4, 4).ToArray());
        }
    }
}